package com.hong.whitelist;



import com.alibaba.fastjson2.JSON;
import com.hong.whitelist.annotation.DoWhiteList;


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Arrays;

// 切面注解
// Spring 扫描注解
// 日志注解
@Aspect
@Component
@Slf4j
public class DoJoinPoint {

    // 注入白名单配置类对象
    @Resource
    private String whiteListConfig;

    // 定义切点
    @Pointcut("@annotation(com.hong.whitelist.annotation.DoWhiteList)")
    public void aopPoint(){}

    @Around("aopPoint()")
    public Object doRouter(ProceedingJoinPoint jp) throws Throwable {
        // 获取内容
        Method method = getMethod(jp);
        // 获取注解对象
        DoWhiteList whiteList = method.getAnnotation(DoWhiteList.class);

        // 读取注解上的配置，读取方法参数上的具体值
        String keyValue = getFiledValue(whiteList.key(), jp.getArgs());

        // 没有设置白名单
        if(null == keyValue || "".equals(keyValue)) return jp.proceed();


        // 读取配置
        String [] users = whiteListConfig.split(",");

        // 白名单过滤  如果在白名单内的就执行
        for(String user : users){
            if(keyValue.equals(user)){
                return jp.proceed();
            }
        }

        return returnObject(whiteList,method);
    }




    // 自定义方法 getMethod
    private Method getMethod(JoinPoint jp) throws NoSuchMethodException {
        Signature sig = jp.getSignature();
        MethodSignature methodSignature = (MethodSignature) sig;
        return jp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
    }


    // 自定义方法 返回数据 returnObject  拒绝之后的返回信息


    private Object returnObject(DoWhiteList whiteList,Method method) throws InstantiationException, IllegalAccessException {


        Class<?> returnType = method.getReturnType();
        // 获取用户自定义的返回值
        String returnJson = whiteList.returnJson();
        if("".equals(returnJson)){
            return returnType.newInstance();
        }
        return JSON.parseObject(returnJson,returnType);

    }

    // 获取注解定义的属性
    private String getFiledValue(String filed,Object[] args) {
        String filedValue = null;
        for(Object arg : args ){
            try {
                // 等于null 或者等于”“说明还没找，需要继续匹配
                if (null == filedValue || "".equals(filedValue)) {
                    // 从当前对象 arg 中获取指定属性 filed 的值，并赋给 filedValue 变量。
                    filedValue = BeanUtils.getProperty(arg, filed);
                } else {
                    break;
                }
            }catch (Exception e){
                if(args.length == 1){
                    return args[0].toString();
                }
            }
        }
        return filedValue;
    }








}
